 1.ClickHouse数据类型之整型
   
   固定长度的整型，包括有符号整型或无符号整型。
   整型范围(-2n-1~2n-1-1)：
   Int8    [-128 : 127]                                 1
   Int16  - [-32768 : 32767]                            2
   Int32   [-2147483648 : 2147483647]                   3
   Int64   [-9223372036854775808 : 9223372036854775807] 4
   名称 范围 大小(字节)
   无符号整型范围(0~2n-1)：
   名称                范围                      大小（字节）
   UInt8              [0 : 255]                  1
   UInt16[0 : 65535]  [0 : 65535]                2
   UInt32             [0 : 4294967295]           3
   UInt64             [0 : 18446744073709551615] 4
 
 2.浮点型
   
   名称    大小（字节） 有效精度（位数） 传统
   Float32 4               7             Float
   Float64 8              16             Double
 
   建议尽可能以整数形式存储数据。例如，将固定精度的数字转换为整数值，如时间用毫秒为单位表示，因为浮点型进
行计算时可能引起四舍五入的误差。
:) select 1-0.9
┌───────minus(1, 0.9)─┐
│ 0.09999999999999998 │
└─────────────────────┘
   与标准SQL相比，ClickHouse 支持以下类别的浮点数：
   Inf-正无穷：
:) select 1/0
┌─divide(1, 0)─┐
│ inf │
└──────────────┘
   -Inf-负无穷：
:) select -1/0
┌─divide(1, 0)─┐
│ -inf │
└──────────────┘
   NaN-非数字：
:) select 0/0
┌─divide(0, 0)─┐
│ nan │
└──────────────┘

 3.Decimal
   
   如果要求更高精度，可以选择Decimal类型
   格式：Decimal（P,S)
   P:代表精度，决定总位数（正数部分+小数部分），取值范围0-38
   S:代表规模，决定小数位数，取值范围是0-P   
   ClickHouse对Decimal提供三种简写：
   Decimal32，Decimal64，Decimal128
   1).相加、减精度取大
SELECT toDecimal32(2, 4) + toDecimal32(2, 2)
┌─plus(toDecimal64(2, 4), toDecimal32(2, 2))─┐
│ 4.0000 │
└────────────────────────────────────────────┘

SELECT toDecimal32(4, 4) - toDecimal32(2, 2)
┌─minus(toDecimal32(4, 4), toDecimal32(2, 2))─┐
│ 2.0000 │
└─────────────────────────────────────────────┘
   2).相乘精度取和
SELECT toDecimal32(2, 2) * toDecimal32(4, 4)
┌─multiply(toDecimal32(2, 2), toDecimal32(4, 4))─┐
│ 8.000000 │
└────────────────────────────────────────────────┘
   3).相除精度取被除数
SELECT toDecimal32(4, 4) / toDecimal32(2, 2)
┌─divide(toDecimal32(4, 4), toDecimal32(2, 2))─┐
│ 2.0000 │
└──────────────────────────────────────────────┘

 4.字符串
   
   String
   字符串可以任意长度的。它可以包含任意的字节集，包含空字节。
   FixedString(N)
   固定长度 N 的字符串，N 必须是严格的正自然数。当服务端读取长度小于 N 的字符串时候，通过在字符串末尾添加
空字节来达到 N 字节长度。 当服务端读取长度大于 N 的字符串时候，将返回错误消息。
SELECT
toFixedString('abc', 5),
LENGTH(toFixedString('abc', 5)) AS LENGTH
┌─toFixedString('abc', 5)─┬─LENGTH─┐
│ abc │ 5 │
└─────────────────────────┴────────┘
   
   UUID
   ClickHouse将UUID这种在传统数据库中充当主键的类型直接做成了数据类型
CREATE TABLE UUID_TEST
(
`c1` UUID,
`c2` String
)
ENGINE = Memory

   插入数据
	insert into UUID_TEST select generateUUIDv4(),'t1';
	insert into UUID_TEST(c2) values('t2');
   查询结果：
SELECT *
FROM UUID_TEST
┌───────────────────────────────────c1─┬─c2─┐
│ 7508ccbd-16b9-451d-b74e-3768bc6b91a9 │ t1 │
└──────────────────────────────────────┴────┘
┌───────────────────────────────────c1─┬─c2─┐
│ 00000000-0000-0000-0000-000000000000 │ t2 │
└──────────────────────────────────────┴────┘
 
 5.枚举类型
   
   包括 Enum8 和 Enum16 类型。Enum 保存 'string'= integer 的对应关系。
   Enum8 用 'String'= Int8 对描述。
   Enum16 用 'String'= Int16 对描述。
   用法演示：
   创建一个带有一个枚举 Enum8('hello' = 1, 'world' = 2) 类型的列：
CREATE TABLE t_enum
(
x Enum8('hello' = 1, 'world' = 2)
)
ENGINE = TinyLog

   这个 x 列只能存储类型定义中列出的值：'hello'或'world'。如果尝试保存任何其他值，ClickHouse 抛出异常。
:) INSERT INTO t_enum VALUES ('hello'), ('world'), ('hello')
   INSERT INTO t_enum VALUES
Ok.
3 rows in set. Elapsed: 0.002 sec.
:) insert into t_enum values('a')
INSERT INTO t_enum VALUES
Exception on client:
Code: 49. DB::Exception: Unknown element 'a' for type Enum8('hello' = 1, 'world' = 2)

   从表中查询数据时，ClickHouse 从 Enum 中输出字符串值。
SELECT * FROM t_enum
┌─x─────┐
│ hello │
│ world │
│ hello │
└───────┘

   如果需要看到对应行的数值，则必须将 Enum 值转换为整数类型。
SELECT CAST(x, 'Int8') FROM t_enum
┌─CAST(x, 'Int8')─┐
│ 1 │
│ 2 │
│ 1 │
└─────────────────┘

   为什么需要枚举类型？
   后续对枚举的操作：排序、分组、去重、过滤等，会使用Int类型的Value值

 6.数组
    
   Array(T)：由 T 类型元素组成的数组。
   T 可以是任意类型，包含数组类型。 但不推荐使用多维数组，ClickHouse 对多维数组的支持有限。例如，不能在
MergeTree 表中存储多维数组。
   可以使用array函数来创建数组：
   array(T)
   也可以使用方括号：ClickHouse能够自动推断数据类型
   []
   创建数组案例：
:) SELECT array(1, 2.0) AS x, toTypeName(x) --数组中可以有不同的数据类型，但是需要相互兼容。
┌─x─────┬─toTypeName(array(1, 2))─┐
│ [1,2] │ Array(UInt8) │
└───────┴─────────────────────────┘
1 rows in set. Elapsed: 0.002 sec.
:) SELECT [1, 2] AS x, toTypeName(x)
┌─x─────┬─toTypeName([1, 2])─┐
│ [1,2] │ Array(UInt8) │
└───────┴────────────────────┘
1 rows in set. Elapsed: 0.002 sec.

   如果是声明表字段的时候，需要指明数据类型：
CREATE TABLE Array_test
(
`c1` Array(String)
)
ENGINE = memory

 7.元组
   
   Tuple(T1, T2, ...)：元组，其中每个元素都有单独的类型。
   创建元组的示例： 
:) SELECT tuple(1,'a') AS x, toTypeName(x)
SELECT
(1, 'a') AS x,
toTypeName(x)
┌─x───────┬─toTypeName(tuple(1, 'a'))─┐
│ (1,'a') │ Tuple(UInt8, String) │
└─────────┴───────────────────────────┘
1 rows in set. Elapsed: 0.021 sec.

   在定义表字段的时候也需要指明数据类型

 8.Date、DateTime
   
   日期类型，用两个字节存储，表示从 1970-01-01 (无符号) 到当前的日期值。 

 9.布尔型
   
   没有单独的类型来存储布尔值。可以使用 UInt8 类型，取值限制为 0 或 1。   